'''
Created on Dec 4, 2012

@author: laura
'''

from ChessConsts import ChessConsts
from ChessCommonUtils import ChessCommonUtils

# Apparently I'm using old-style classes here and should inherit from object
# for much goodness - TODO
class Threatened:
    ''' Refactored the complex isThreatened method in here from ChessBoard. 
    Also refactored some common constants and methods out of ChessBoard and into
    ChessConsts and ChessCommonUtils to support this (not all of the candidate
    constants and methods were moved, due to issues of practicality with so 
    many devs changing stuff intensely. 
    
    I've broken the primary method into four methods, which improves readability a
    bit. There are still candidates in here for making these methods a bit more
    readable and perhaps removing some code duplication in terms of the black/white 
    logic, not sure how far I will get with this in the time. '''
    
    
    @staticmethod
    def isThreatened(board, lx,ly,player):
        if(Threatened.threatenedByPawn(board, lx, ly, player)):
            return True
        if(Threatened.threatenedByKnight(board, lx, ly, player)):
            return True
        if(Threatened.threatenedByRookBishopOrRoyals(board, lx, ly, player)):
            return True
        
        return False
    
    @staticmethod
    def threatenedByPawn(board, lx, ly, player):
        if player == ChessConsts.WHITE:
            if lx<7 and ly>0 and board[ly-1][lx+1] == 'p':
                return True
            elif lx>0 and ly>0 and board[ly-1][lx-1] == 'p':
                return True
        else:  
            if lx<7 and ly<7 and board[ly+1][lx+1] == 'P':
                return True
            elif lx>0 and ly<7 and board[ly+1][lx-1] == 'P':
                return True
            
    @staticmethod
    def threatenedByKnight(board, lx, ly, player):
        m =[(lx+1,ly+2),(lx+2,ly+1),(lx+2,ly-1),(lx+1,ly-2),(lx-1,ly+2),(lx-2,ly+1),(lx-1,ly-2),(lx-2,ly-1)]
        for p in m:
            if p[0] >= 0 and p[0] <= 7 and p[1] >= 0 and p[1] <= 7: 
                if board[p[1]][p[0]] == "n" and player==ChessConsts.WHITE:
                    return True                
                elif board[p[1]][p[0]] == "N" and player==ChessConsts.BLACK:
                    return True  
    
    @staticmethod        
    def threatenedByRookBishopOrRoyals(board, lx, ly, player):
        dirs = [(1,0),(-1,0),(0,1),(0,-1),(1,1),(-1,1),(1,-1),(-1,-1)]        
        for d in dirs:
            x = lx 
            y = ly
            dx,dy = d
            steps = 0
            while True:
                steps+=1
                x+=dx
                y+=dy
                if x<0 or x>7 or y<0 or y>7:
                    break
                if ChessCommonUtils.isFree(board,x,y):
                    continue
                elif ChessCommonUtils.getColor(board,x,y)==player:
                    break
                else:
                    p = board[y][x].upper()
                    if p == 'K' and steps == 1:
                        return True
                    elif p == 'Q':
                        return True
                    elif p == 'R' and abs(dx) != abs(dy):
                        return True
                    elif p == 'B' and abs(dx) == abs(dy):
                        return True 
                    break
